﻿namespace ScrumFactory.Services.Clients
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.Runtime.Serialization.Json;
    using Microsoft.Http;

    [Export(typeof(IBacklogService))]
    public class BacklogServiceClient : IBacklogService
    {
        private Uri baseUrl;

        [ImportingConstructor()]
        public BacklogServiceClient([Import("BacklogServiceUrl")] string url)
            : this(new Uri(url))
        {
        }

        public BacklogServiceClient(Uri url)
        {
            this.baseUrl = url;
        }

        public ICollection<BacklogItem> GetCurrentBacklog(string projectUId)
        {            
            var client = new HttpClient(new Uri(this.baseUrl, "Backlogs/" + projectUId + "/?planning=current"));
            HttpResponseMessage response = client.Send(HttpMethod.GET);
            RestServiceUtil.HandleHTTPErrorCode(response);           
            return response.Content.ReadAsJsonDataContract<ICollection<BacklogItem>>();            
        }

        public ICollection<BacklogItem> GetBacklog(string projectUId) {
            var client = new HttpClient(new Uri(this.baseUrl, "Backlogs/" + projectUId));
            HttpResponseMessage response = client.Send(HttpMethod.GET);
            RestServiceUtil.HandleHTTPErrorCode(response);
            return response.Content.ReadAsJsonDataContract<ICollection<BacklogItem>>();
        }

        public BacklogItem GetBacklogItem(string backlogItemUId) {
            var client = new HttpClient(new Uri(this.baseUrl, "BacklogItems/" + backlogItemUId));
            HttpResponseMessage response = client.Send(HttpMethod.GET);
            RestServiceUtil.HandleHTTPErrorCode(response);           
            return response.Content.ReadAsJsonDataContract<BacklogItem>();
        }

        /// <summary>
        /// Saves a backlog item.
        /// If the item planned hours is old, it also replan the hours for the current planning number.
        /// </summary>
        /// <param name="item">The iem to be saved</param>
        public void AddBacklogItem(BacklogItem item) {

            if (item.Project == null)
                throw new Exception("Can not save a backlogitem without a Project property");

            var client = new HttpClient();
            HttpResponseMessage response = client.Send(HttpMethod.POST, new Uri(this.baseUrl, "BacklogItems"), HttpContentExtensions.CreateJsonDataContract(item));
            RestServiceUtil.HandleHTTPErrorCode(response);
        }

        /// <summary>
        /// Saves a backlog item.
        /// If the item planned hours is old, it also replan the hours for the current planning number.
        /// </summary>
        /// <param name="item">The iem to be saved</param>
        public void UpdateBacklogItem(BacklogItem item) {

            if (item.Project == null)
                throw new Exception("Can not save a backlogitem without a null Project property");

            // if the item planning is old, add planned hours for the current planning
            int currentPlanningNumber = item.Project.CurrentPlanningNumber;            
            if (currentPlanningNumber > item.PlanningNumber) {

                List<PlannedHour> replannedHours = new List<PlannedHour>();
                foreach (PlannedHour h in item.PlannedHours)
                    replannedHours.Add(new PlannedHour() {
                        BacklogItemUId = h.BacklogItemUId,
                        PlanningNumber = currentPlanningNumber,
                        SprintNumber = h.SprintNumber,
                        RoleUId = h.RoleUId,
                        Hours = h.Hours
                    });

                item.PlannedHours = replannedHours;
            }

            var client = new HttpClient();
            HttpResponseMessage response = client.Send(HttpMethod.PUT, new Uri(this.baseUrl, "BacklogItems"), HttpContentExtensions.CreateJsonDataContract(item));            
            RestServiceUtil.HandleHTTPErrorCode(response);           
        }

        /// <summary>
        /// Saves a backlog item, ignoring its hours.
        /// </summary>
        /// <param name="item">The iem to be saved</param>
        public void UpdateBacklogItemIgnoringHours(BacklogItem item) {
            var client = new HttpClient();
            HttpResponseMessage response = client.Send(HttpMethod.PUT, new Uri(this.baseUrl, "BacklogItems?IgnoreHours=true"), HttpContentExtensions.CreateJsonDataContract(item));
            RestServiceUtil.HandleHTTPErrorCode(response);           
        }

        public void DeleteBacklogItem(string backlogItemUId) {
            var client = new HttpClient();
            HttpResponseMessage response = client.Send(HttpMethod.DELETE, new Uri(this.baseUrl, "BacklogItems/" + backlogItemUId));
            RestServiceUtil.HandleHTTPErrorCode(response);           
        }

        public void SaveBacklog(string projectUId, ICollection<BacklogItem> backlogItems)
        {
            var client = new HttpClient();
            HttpResponseMessage response = client.Send(HttpMethod.POST, new Uri(this.baseUrl, "Backlogs/" + projectUId), HttpContentExtensions.CreateJsonDataContract(backlogItems));
            RestServiceUtil.HandleHTTPErrorCode(response);           
        }


        public ICollection<BurndownLeftHoursByDay> GetBurndownHoursByDay(string projectUId) {
            var client = new HttpClient(new Uri(this.baseUrl, "BurndownHoursByDay/" + projectUId));
            HttpResponseMessage response = client.Send(HttpMethod.GET);
            RestServiceUtil.HandleHTTPErrorCode(response);
            return response.Content.ReadAsJsonDataContract<ICollection<BurndownLeftHoursByDay>>();
        }

        public ICollection<BurndownLeftHoursByDay> GetBurndownHoursByDayProposalPlanning(string projectUId) {
            var client = new HttpClient(new Uri(this.baseUrl, "BurndownHoursByDay/" + projectUId +"/?planning=proposal"));
            HttpResponseMessage response = client.Send(HttpMethod.GET);
            RestServiceUtil.HandleHTTPErrorCode(response);
            return response.Content.ReadAsJsonDataContract<ICollection<BurndownLeftHoursByDay>>();
        }

        public ICollection<BurndownLeftHoursByDay> GetBurndownHoursByDayFirstPlanning(string projectUId) {
            var client = new HttpClient(new Uri(this.baseUrl, "BurndownHoursByDay/" + projectUId + "/?planning=first"));
            HttpResponseMessage response = client.Send(HttpMethod.GET);
            RestServiceUtil.HandleHTTPErrorCode(response);
            return response.Content.ReadAsJsonDataContract<ICollection<BurndownLeftHoursByDay>>();
        }
       
    }
}
